package com.lantu.core.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lantu.annotation.CurrentUser;
import com.lantu.annotation.NotLogin;
import com.lantu.constant.CommonConstants;
import com.lantu.core.entity.User;
import com.lantu.core.service.IUserService;
import com.lantu.dto.user.UserDTO;
import com.lantu.dto.user.UserLoginDTO;
import com.lantu.pojo.user.LoginUser;
import com.lantu.vo.Result;
import com.lantu.vo.user.UserListVO;
import com.lantu.vo.user.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author binyuhuang
 * @since 2023-02-07
 */
@RestController
@RequestMapping("/sys/user")
@CrossOrigin   //跨域处理
public class UserController {
    @Autowired
    private IUserService userService;

    @NotLogin
    @PostMapping("/login")
    public Result<?> login(HttpServletRequest request, @RequestBody UserLoginDTO dto) throws Exception {
        if (!ObjectUtils.isEmpty(dto)) {
            LoginUser loginUser = userService.login(request, dto);
            if (loginUser != null) {
                return Result.success(loginUser);
            }
        }
        return Result.fail(20002, "用户名或密码错误");
    }

    @GetMapping("/info")
    public Result<Map<String, Object>> getUserInfo(@RequestParam("token") String token) {
        // 根据token获取用户信息，redis
        Map<String, Object> data = userService.getUserInfo(token);
        if (data != null) {
            return Result.success(data);
        }
        return Result.fail(20003, "登录信息无效，请重新登录");
    }

    @PostMapping("/logout")
    public Result<?> logout(@RequestHeader("X-Token") String token) {
        userService.logout(token);
        return Result.success();
    }

    @GetMapping("/list")
    public Result<Map<String, Object>> getUserList(UserDTO dto,
                                                   @RequestParam(value = "pageNo") Long pageNo,
                                                   @RequestParam(value = "pageSize") Long pageSize, @CurrentUser User loginUser) {

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasLength(dto.getUsername()), User::getUsername, dto.getUsername());
        wrapper.eq(StringUtils.hasLength(dto.getPhone()), User::getPhone, dto.getPhone());
        wrapper.ne(User::getId, loginUser.getId());
        wrapper.orderByDesc(User::getCreateTime, User::getId);
        wrapper.select(User::getId, User::getUsername, User::getPhone, User::getStatus, User::getEmail);

        Page<User> page = new Page<>(pageNo, pageSize);
        userService.page(page, wrapper);

        List<UserListVO> list = page.getRecords().stream().map(UserListVO::newInstance).collect(Collectors.toList());

        Map<String, Object> data = new HashMap<>();
        data.put("total", page.getTotal());
        data.put("rows", list);

        return Result.success(data);
    }



    @PostMapping
    public Result<?> addUser(@RequestBody UserDTO dto, @CurrentUser User loginUser) throws Exception {
        if(userService.saveUser(loginUser, dto))return Result.success("新增用户成功");
        return Result.fail("新增失败");
    }

    @PutMapping
    public Result<?> updateUser(@RequestBody UserDTO dto, @CurrentUser User loginUser) throws Exception {
        if(userService.saveUser(loginUser, dto))return Result.success("修改用户成功");
        return Result.fail("修改失败");
    }

    @GetMapping("/{id}")
    public Result<?> getUserById(@PathVariable("id") String id) {
        return Result.success(UserVO.newInstance(userService.getById(id)));
    }

    @DeleteMapping("/{id}")
    public Result<?> deleteUserById(@PathVariable("id") String id) {
        User sourceUser = userService.getById(id);
        if(!ObjectUtils.isEmpty(sourceUser) && StrUtil.isNotEmpty(sourceUser.getId())){
            userService.removeById(id);
            return Result.success("删除用户成功");
        }
        return Result.fail("用户不存在或已被删除");
    }

    @PostMapping("/updateStatus")
    public Result<?> updateStatus(@RequestBody UserDTO dto, @CurrentUser User loginUser) {
        User sourceUser = userService.getById(dto.getId());
        sourceUser.setStatus(dto.getStatus());
        sourceUser.updateBy(loginUser.getUsername());
        userService.updateById(sourceUser);

        //如果修改为封禁状态则强制踢出登录，拦截器会拦截前端请求的token在redis验证有效性
        if(!Objects.equals(sourceUser.getStatus(), CommonConstants.USER_NORMAL_STATUS)){
            //查询该用户下的所有有效token
            Set<String> tokens = userService.getTokensByUserId(sourceUser.getId());
            //强制退出登录，将token都注销掉
            userService.logouts(tokens);
        }
        return Result.success("操作成功");
    }


    @GetMapping("/online/list")
    public Result<?> getOnLineUserList(@RequestParam(value = "pageNo") Integer pageNo,
                                       @RequestParam(value = "pageSize") Integer pageSize){

        List<LoginUser> allOnLineUser = userService.getALLOnLineUser();
        int total = allOnLineUser.size();
        // 计算起始索引和结束索引
        int startIndex = (pageNo - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, allOnLineUser.size());

        allOnLineUser = allOnLineUser.subList(startIndex, endIndex);

        Map<String, Object> data = new HashMap<>();
        data.put("total", total);
        data.put("rows", allOnLineUser);
        return Result.success(data);
    }


    @GetMapping("/online/{id}")
    public Result<?> getOnlineUserById(@PathVariable("id") String id) {
        return Result.success(userService.getLoginUserByUserId(id));
    }


    @GetMapping("/online/logout/{token}")
    public Result<?> onlineLogout(@PathVariable("token") String token) {
        return logout(token);
    }
}
